package com.lovo.common.util;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.UUID;

/**
 * 消息队列发送和接收消息的工具类
 */
@Component
public class MQUtil {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 发送消息给交换机，并指定对应的路由键和消息内容
     * @param exchangeName
     * @param routingKey
     * @param message
     */
    public void send(String exchangeName,String routingKey,Object message){
        // 消息发送，带MessageId
        MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message msg) throws AmqpException {
                final MessageProperties messageProperties = msg.getMessageProperties();
                // 消息id
                messageProperties.setMessageId(UUID.randomUUID().toString());
                return msg;
            }
        };
        this.rabbitTemplate.convertAndSend(exchangeName,routingKey,message,messagePostProcessor);
    }

    /**
     * 确认消息已被消费
     * @param message 消费的消息对象
     * @param channel 通信的通道
     */
    public void ack(Message message, Channel channel){
        try {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 确认消息消费失败
     * @param message 消费的消息对象
     * @param channel 通信的通道
     */
    public void nack(Message message, Channel channel){
        try {
            channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
